package com.mioto.ld.communication.mqtt.protocol;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.mioto.ld.communication.mqtt.MqttHelper;
import com.mioto.ld.communication.mqtt.protocol.model.DeviceMTypeEnum;
import com.mioto.ld.communication.mqtt.protocol.model.Message;
import com.mioto.ld.communication.mqtt.protocol.model.ReplyStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @author mioto-qinxj
 * @date 2024/5/8
 * @desc 上下文类，持有策略接口
 */
@Slf4j
@Component
public class ReceiptStrategyContext {

    @Async
    public void resolver(Integer mqttClientId,String data){
        Message packetMessage = messageParse(data);
       if (ObjectUtil.isNotNull(packetMessage)) {
           ReplyStatusEnum replyStatusEnum = ReplyStatusEnum.SERVER_REPLY_SUCCESS;
           DeviceMTypeEnum deviceMTypeEnum = DeviceMTypeEnum.getInstance(packetMessage.getMtype());
           //如果不是认证消息且没有存设备序列表，说明没有认证
           if (!StrUtil.equals(deviceMTypeEnum.name(),DeviceMTypeEnum.DEVICE_AUTH.name()) && !MqttHelper.containsSn(packetMessage.getSn())){
               log.warn("设备 - {} 没有认证,需重新发送认证信息",packetMessage.getSn());
               replyStatusEnum = ReplyStatusEnum.SERVER_REPLY_UNAUTHENTICATED;
               MqttHelper.reply(mqttClientId, packetMessage.getSn(), replyStatusEnum);
               return;
           }

           //缓存保存设备通讯的mqtt客户端id
           if (StrUtil.equals(deviceMTypeEnum.name(),DeviceMTypeEnum.DEVICE_AUTH.name())){
               MqttHelper.putDeviceConnects(packetMessage.getSn(),mqttClientId);
           }

           try {
               deviceMTypeEnum.getHandlerClazz().protocolHandler(packetMessage);
           }catch (Exception e){
               replyStatusEnum = ReplyStatusEnum.SERVER_REPLY_FAULT;
           }

           if (deviceMTypeEnum.isReply()) {
               log.info("回复设备 - {} 信息",packetMessage.getSn());
               MqttHelper.reply(mqttClientId, packetMessage.getSn(), replyStatusEnum);
           }
       }
    }


    /**
     * 消息转换实体bean
     * @param data
     * @return
     */
    private Message messageParse(String data){
        try {
            Gson gson = new GsonBuilder().registerTypeAdapter(Message.class, new PayloadDeserializer()).create();
            return gson.fromJson(data, Message.class);
        }catch (JsonParseException jsonParseException){
            log.error("消息格式不支持 - {}",data);
        }
        return null;
    }
}
